﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FeatureModelCore.FMTypes;
using Collections.TreeCollections;
using System.Xml.Linq;

namespace FeatureModelCore.Configuration
{
    public enum ConstraintType
    {
        Require, Exclude
    }
    public class ConfigConstraint
    {
        #region Xml Symbol
        private readonly static string _XML_TYPE = "CrossTreeConstraintType";
        private readonly static string _XML_IDA = "IdentifyA";
        private readonly static string _XML_IDB = "IdentifyB";
        #endregion

        #region Properties
        public ConfigFeatureModel Configuration { get { return _configuration; } internal set { _configuration = value; } }
        public ConfigNode NodeA { get { return (ConfigNode)_configuration[_nodeIdA]; } }
        public ConfigNode NodeB { get { return (ConfigNode)_configuration[_nodeIdB]; } }
        public ConstraintType Type { get { return _type; } set { _type = value; } }
        public string Name { get { return this.ToString(); } }
        #endregion

        #region Feilds
        private ConfigFeatureModel _configuration;
        private TreeNodeIdentify _nodeIdA;
        private TreeNodeIdentify _nodeIdB;
        private ConstraintType _type;
        #endregion

        public ConfigConstraint(TreeNodeIdentify nodeAId
            , TreeNodeIdentify nodeBId, ConstraintType type)
        {
            _nodeIdA = nodeAId;
            _nodeIdB = nodeBId;
            _type = type;
        }

        public override string ToString()
        {
            return string.Format("{0} {1} {2}"
                , this.NodeA.Name
                , this.Type.ToString()
                , this.NodeB.Name);
        }

        #region Xml Parser
        /// <summary>
        /// Xml Parser
        /// </summary>
        /// <returns></returns>
        public XElement ToXElem()
        {
            XElement xelem = new XElement(this.GetType().Name);
            xelem.Add(new XAttribute(_XML_IDA, _nodeIdA.ToString()));
            xelem.Add(new XAttribute(_XML_IDB, _nodeIdB.ToString()));
            xelem.Add(new XAttribute(_XML_TYPE, _type.ToString()));

            return xelem;
        }
        /// <summary>
        /// Xml Parser
        /// </summary>
        /// <param name="xelem"></param>
        /// <returns></returns>
        public static ConfigConstraint XmlParser(XElement xelem)
        {
            string idAStr = xelem.Attribute(_XML_IDA).Value;
            string idBStr = xelem.Attribute(_XML_IDB).Value;
            string typeStr = xelem.Attribute(_XML_TYPE).Value;

            TreeNodeIdentify idA = new TreeNodeIdentify(idAStr);
            TreeNodeIdentify idB = new TreeNodeIdentify(idBStr);
            ConstraintType type = (ConstraintType)Enum.Parse(
                typeof(ConstraintType), typeStr);

            ConfigConstraint cons = new ConfigConstraint(idA, idB, type);
            return cons;
        }
        #endregion

        #region Equals
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            ConfigConstraint cons = obj as ConfigConstraint;
            if (cons == null)
            {
                return false;
            }

            return this._type == cons._type
                && this._nodeIdA.Equals(cons._nodeIdA)
                && this._nodeIdB.Equals(cons._nodeIdB);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        #endregion
    }
}
